package com.example.java_gobang.game.service;

import com.example.java_gobang.game.vo.MatchResponse;
import com.example.java_gobang.game.model.Room;
import com.example.java_gobang.model.User;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import java.io.IOException;
import java.util.LinkedList;
import java.util.Queue;

@Slf4j
@Component
public class Matcher {

    private final ObjectMapper mapper = new ObjectMapper();

    // 匹配队列
    private final Queue<User> normalQueue = new LinkedList<>();
    private final Queue<User> highQueue = new LinkedList<>();
    private final Queue<User> veryHighQueue = new LinkedList<>();

    @Autowired
    private OnlineUserManager onlineUserManager;

    @Autowired
    private RoomManager roomManager;

    public void add(User user) {
        if (user.getScore() < 2000) {
            synchronized (normalQueue) {
                normalQueue.offer(user);
                normalQueue.notify();
            }
            log.info("将玩家:{} 加入到 normalQueue 中!", user.getUsername());
        } else if (user.getScore() >= 2000 && user.getScore() < 3000) {
            synchronized (highQueue) {
                highQueue.offer(user);
                highQueue.notify();
            }
            log.info("将玩家:{} 加入到 highQueue 中!", user.getUsername());
        } else {
            synchronized (veryHighQueue) {
                veryHighQueue.offer(user);
                veryHighQueue.notify();
            }
            log.info("将玩家:{} 加入到 veryHighQueue 中!", user.getUsername());
        }
    }

    public void remove(User user) {
        if (user.getScore() < 2000) {
            synchronized (normalQueue) {
                normalQueue.remove(user);
            }
        } else if (user.getScore() >= 2000 && user.getScore() < 3000) {
            synchronized (highQueue) {
                highQueue.remove(user);
            }
        } else {
            synchronized (veryHighQueue) {
                veryHighQueue.remove(user);
            }
        }
        log.info("将玩家:{} 移除匹配队列!", user.getUsername());
    }

    public Matcher() {
        Thread t1 = new Thread(() -> {
            while (true) {
                handlerMatch(normalQueue);
            }
        });
        t1.start();
        Thread t2 = new Thread(() -> {
            while (true) {
                handlerMatch(highQueue);
            }
        });
        t2.start();
        Thread t3 = new Thread(() -> {
            while (true) {
                handlerMatch(veryHighQueue);
            }
        });
        t3.start();
    }

    private void handlerMatch(Queue<User> matchQueue) {
        try {
            synchronized (matchQueue) {
                while (matchQueue.size() < 2) {
                    matchQueue.wait();
                }

                // 从队列中取出两个玩家
                User player1 = matchQueue.poll();
                User player2 = matchQueue.poll();
                log.info("成功匹配两位玩家: {},{}", player1.getUsername(), player2.getUsername());

                // 获取玩家的 WebSocket 会话
                WebSocketSession session1 = onlineUserManager.getFromGameHall(player1.getUserId());
                WebSocketSession session2 = onlineUserManager.getFromGameHall(player2.getUserId());

                // 如果两者都不存在
                if (session1 == null && session2 == null) {
                    log.warn("两个玩家的会话都不存在: {}, {}", player1.getUsername(), player2.getUsername());
                    return;
                }

                // 有一方不存在，把另一方放回队列
                if (session1 == null) {
                    log.warn("玩家 {} 的会话不存在，将 {} 放回队列", player1.getUsername(), player2.getUsername());
                    matchQueue.add(player2);
                }
                if (session2 == null) {
                    log.warn("玩家 {} 的会话不存在，将 {} 放回队列", player2.getUsername(), player1.getUsername());
                    matchQueue.add(player1);
                }

                // 如果两者是同一个会话，忽略这个匹配
                if (session1 == session2) {
                    log.warn("玩家 {} 和 {} 使用的是同一个会话，将其放回队列", player1.getUsername(), player2.getUsername());
                    matchQueue.add(player1);
                    matchQueue.add(player2);
                }

                // 将玩家移出大厅
                onlineUserManager.exitGameHall(player1.getUserId());
                onlineUserManager.exitGameHall(player2.getUserId());

                // 创建玩家所需的房间
                roomManager.add(new Room(), player1.getUserId(), player2.getUserId());

                // 将匹配成功进入房间的反馈信息发送给玩家
                MatchResponse matchResponse1 = new MatchResponse();
                matchResponse1.setOk(true);
                matchResponse1.setMessage("matchSuccess");
                String json1 = mapper.writeValueAsString(matchResponse1);
                session1.sendMessage(new TextMessage(json1));

                MatchResponse matchResponse2 = new MatchResponse();
                matchResponse2.setOk(true);
                matchResponse2.setMessage("matchSuccess");
                String json2 = mapper.writeValueAsString(matchResponse2);
                session2.sendMessage(new TextMessage(json2));
            }
        } catch (IOException | InterruptedException e) {
            log.error("匹配过程中发生错误", e);
        }
    }
}
